const http = require('http')
const url  = require('url')
const Stream = require('stream')
class Koa { 
    constructor() { 
        this.middleware = []
    }
    use(fn) {
        this.middleware.push(fn)
    }
    compose(middleware,ctx) {
        return dispatch(0)
        function dispatch(i) { 
            let fn = middleware[i]
            if(!fn) return Promise.resolve()
            // middleware[i](ctx, () => dispatch(i+1))

            // 这里必须 return dispatch
            let next = () => { return dispatch(i+1)} 
            return Promise.resolve(fn(ctx, next))
        }
    }
    handleResponse(ctx){
        let {req,res,body} = ctx;
        console.log(body);
        // debugger
        if(typeof body === 'string' || body instanceof Buffer){
            // debugger
            res.end(ctx.body)
        } else if(body instanceof Stream){
            // debugger
            body.pipe(res)
            // debugger
        }
        // debugger
    }
    listen(port) {
        const middleware = this.middleware
        http.createServer((req, res) => { 
            let ctx = { req, res };
            ctx.path = url.parse(req.url).pathname
            // debugger
            // koa 2 原理
            console.log(`server created at port ${port}`)
            this.compose(middleware, ctx).then(() => {
                // debugger
                this.handleResponse(ctx)
            }).catch(err => {
                debugger
                console.log(err)
            })
            // koa 1 原理
            // (middleware.reduceRight((val, item) => { 
            //         // console.log(item.bind(null, ctx, val)(),'bind');
            //         return item.bind(null, ctx, val);
            //     }, (function () { })))()
        }).listen(port)
    }
}
module.exports = Koa